﻿'This program is free software: you can redistribute it and/or modify
'it under the terms of the GNU General Public License as published by
'the Free Software Foundation, either version 3 of the License, or
'(at your option) any later version.

'This program is distributed in the hope that it will be useful,
'but WITHOUT ANY WARRANTY; without even the implied warranty of
'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'GNU General Public License for more details.

'You should have received a copy of the GNU General Public License
'along with this program.  If not, see <http://www.gnu.org/licenses/>.

Imports System.Net
Imports System.Web
Imports System.IO
Imports System.Text

Public Enum Formats
    html
    text
End Enum

''' <summary>
''' This is an implementation of version 1 of the iheartquotes API as specified at the following URL:
''' 
''' http://www.iheartquotes.com/api
''' 
''' </summary>
''' <remarks>William Kevin Manire September 16, 2009</remarks>
Public Class Quote
    Private _quoteText As String
    Private _format As Formats = Formats.text
    Private _max_lines As Integer
    Private _min_lines As Integer
    Private _max_characters As Integer
    Private _min_characters As Integer

    'text options
    Private _show_permalink As Boolean = False
    Private _show_source As Boolean = False


    'HTML options
    Private _font_family As String
    Private _font_color As String
    Private _width As String
    Private _height As String

    Private _sources As New List(Of String)


    Public Shared GeekSources() As String = {"esr", "humorix_misc", "humorix_stories", "joel_on_software", "macintosh", "math", "mav_flame", "osp_rules", "paul_graham", _
                                              "prog_style", "subversion"}
    Public Shared GeneralSources() As String = {"1811_dictionary_of_the_vulgar_tongue", "codehappy", "fortune", "liberty", "literature", "misc", "murphy oneliners", _
                                               "riddles", "rkba", "shlomif", "shlomif_fav", "stephen_wright"}
    Public Shared PopSources() As String = {"calvin", "forrestgump", "friends", "futurama", "holygrail", "powerpuff", "simon_garfunkel", "simpsons_cbg", "simpsons_chalkboard", _
                                            "simpsons_homer", "simpsons_ralph", "south_park", "starwars", "xfiles"}
    Public Shared ReligiousSources() As String = {"bible", "contentions", "osho"}
    Public Shared SciFiSources() As String = {"cryptonomicon", "discworld", "dune", "hitchhiker"}
    Private Shared APIURL = "http://www.iheartquotes.com/api/v1/random"

    ''' <summary>
    ''' return the result in either 'text' or 'html' format. The default is text. There's specific style options for each format.
    ''' </summary>
    Public Property Format() As Formats
        Get
            Return _format
        End Get
        Set(ByVal value As Formats)
            _format = value
        End Set
    End Property

    ''' <summary>
    ''' Once GetQuote() is called this property will contain the quote of the day for the specified settings.
    ''' </summary>
    Public Property QuoteText() As String
        Get
            Return _quoteText
        End Get
        Set(ByVal value As String)
            _quoteText = value
        End Set
    End Property

    ''' <summary>
    ''' maximum number of lines in the quote.
    ''' </summary>
    Public Property MaxLines() As Integer
        Get
            Return _max_lines
        End Get
        Set(ByVal value As Integer)
            _max_lines = value
        End Set
    End Property
    ''' <summary>
    ''' minimum number of lines in the quote.
    ''' </summary>
    Public Property MinLines() As Integer
        Get
            Return _min_lines
        End Get
        Set(ByVal value As Integer)
            _min_lines = value
        End Set
    End Property
    ''' <summary>
    ''' maximum number of characters in the quote.
    ''' </summary>
    Public Property MaxCharacters() As Integer
        Get
            Return _max_characters
        End Get
        Set(ByVal value As Integer)
            _max_characters = value
        End Set
    End Property
    ''' <summary>
    ''' minimum number of characters in the quote.
    ''' </summary>
    Public Property MinCharacters() As Integer
        Get
            Return _min_characters
        End Get
        Set(ByVal value As Integer)
            _min_characters = value
        End Set
    End Property
    ''' <summary>
    ''' show the quote's permalink at the bottom of the text by default.
    ''' </summary>
    Public Property ShowPermalink() As Boolean
        Get
            Return _show_permalink
        End Get
        Set(ByVal value As Boolean)
            _show_permalink = value
        End Set
    End Property
    ''' <summary>
    ''' show the quote's source at the bottom of the text by default. 
    ''' </summary>
    ''' <value></value>
    Public Property ShowSource() As Boolean
        Get
            Return _show_source
        End Get
        Set(ByVal value As Boolean)
            _show_source = value
        End Set
    End Property
    ''' <summary>
    ''' Clears the Sources collection and then adds all of the provided ones
    ''' </summary>
    Public Sub AddAllSources()
        _sources.Clear()
        _sources.AddRange(GeekSources)
        _sources.AddRange(GeneralSources)
        _sources.AddRange(PopSources)
        _sources.AddRange(ReligiousSources)
        _sources.AddRange(SciFiSources)
    End Sub

    ''' <summary>
    ''' For HTML mode only. Specify a font as you would in a CSS file.
    ''' </summary>
    Public Property FontFamily() As String
        Get
            Return _font_family
        End Get
        Set(ByVal value As String)
            _font_family = value
        End Set
    End Property
    ''' <summary>
    ''' For HTML mode only. Specify the color of the text as you would in a CSS file.
    ''' </summary>
    Public Property FontColor() As String
        Get
            Return _font_color
        End Get
        Set(ByVal value As String)
            _font_color = value
        End Set
    End Property
    ''' <summary>
    ''' For HTML mode only. Specify the width of the box containing the quote as you would in a CSS file.
    ''' </summary>
    Public Property Width() As String
        Get
            Return _width
        End Get
        Set(ByVal value As String)
            _width = value
        End Set
    End Property
    ''' <summary>
    ''' For HTML mode only. Specify the height of the box containing the quote as you would in a CSS file.
    ''' </summary>
    Public Property Height() As String
        Get
            Return _height
        End Get
        Set(ByVal value As String)
            _height = value
        End Set
    End Property

    ''' <summary>
    ''' pulls quotes from one of the sources listed.
    ''' 
    ''' From geek: esr humorix_misc humorix_stories joel_on_software macintosh math mav_flame osp_rules paul_graham prog_style subversion 
    '''
    ''' From general: 1811_dictionary_of_the_vulgar_tongue codehappy fortune liberty literature misc murphy oneliners riddles rkba shlomif shlomif_fav stephen_wright 
    '''
    ''' From pop: calvin forrestgump friends futurama holygrail powerpuff simon_garfunkel simpsons_cbg simpsons_chalkboard simpsons_homer simpsons_ralph south_park starwars xfiles 
    '''
    ''' From religious: bible contentions osho 
    '''
    ''' From scifi: cryptonomicon discworld dune hitchhiker 
    '''
    ''' </summary>
    ''' <remarks>Static arrays of quotes are provided</remarks>
    Public Property Sources() As List(Of String)
        Get
            Return _sources
        End Get
        Set(ByVal value As List(Of String))
            _sources = value
        End Set
    End Property

    ''' <summary>
    ''' Gets the quote of the day based on the settings and stores it in the QuoteText property
    ''' </summary>
    Public Function GetQuote() As String
        Try
            Dim qs As New StringBuilder(255)
            Select Case _format
                Case Formats.html
                    qs.Append("?format=html")
                    If Not String.IsNullOrEmpty(_font_family) Then
                        qs.AppendFormat("&font_family={0}", HttpUtility.UrlEncode(_font_family))
                    End If
                    If Not String.IsNullOrEmpty(_font_color) Then
                        qs.AppendFormat("&font_color={0}", HttpUtility.UrlEncode(_font_color))
                    End If
                    If Not String.IsNullOrEmpty(_width) Then
                        qs.AppendFormat("&width={0}", HttpUtility.UrlEncode(_width))
                    End If
                    If Not String.IsNullOrEmpty(_height) Then
                        qs.AppendFormat("&height={0}", HttpUtility.UrlEncode(_height))
                    End If
                Case Formats.text
                    qs.Append("?format=text")
                    qs.AppendFormat("&show_permalink={0}", _show_permalink.ToString)
                    qs.AppendFormat("&show_source={0}", _show_source.ToString)
            End Select
            If _max_characters > 0 Then qs.AppendFormat("&max_characters={0}", _max_characters.ToString)
            If _min_characters > 0 Then qs.AppendFormat("&min_characters={0}", _min_characters.ToString)
            If _max_lines > 0 Then qs.AppendFormat("&max_lines={0}", _max_lines.ToString)
            If _min_lines > 0 Then qs.AppendFormat("&min_lines={0}", _min_lines.ToString)
            If _sources IsNot Nothing AndAlso _sources.Count > 0 Then
                qs.Append("&source=")
                For i As Integer = 0 To _sources.Count - 2
                    qs.Append(HttpUtility.UrlEncode(_sources(i)) + "+")
                Next
                qs.Append(HttpUtility.UrlEncode(_sources.Last))
            End If

            Debug.WriteLine(APIURL + qs.ToString)

            Dim req As HttpWebRequest = HttpWebRequest.Create(APIURL + qs.ToString)
            req.Method = "GET"
            req.UserAgent = "QOTD .Net Library"
            Dim resp As HttpWebResponse = req.GetResponse
            Dim rdr As New StreamReader(resp.GetResponseStream)
            _quoteText = rdr.ReadToEnd
            rdr.Close()
            rdr.Dispose()
            resp.Close()
        Catch ex As Exception
            _quoteText = "An error occured while retrieving the quote of the day: " + ex.Message.ToString
        End Try
        Return _quoteText
    End Function
End Class

